package com.tsoj.tsojquestionservice.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.gson.Gson;

import com.tsoj.common.BaseResponse;
import com.tsoj.common.DeleteRequest;
import com.tsoj.common.ErrorCode;
import com.tsoj.common.ResultUtils;
import com.tsoj.context.ThreadLocalContext;
import com.tsoj.exception.BusinessException;
import com.tsoj.exception.ThrowUtils;
import com.tsoj.model.dto.question.*;
import com.tsoj.model.dto.questionSubmit.QuestionSubmitAddDto;
import com.tsoj.model.dto.questionSubmit.QuestionSubmitQueryDto;
import com.tsoj.model.po.Question;
import com.tsoj.model.po.QuestionSubmit;
import com.tsoj.model.po.User;
import com.tsoj.model.vo.QuestionSubmitVO;
import com.tsoj.model.vo.QuestionVO;
import com.tsoj.propertise.MaxPageSizePropertise;
import com.tsoj.tsojquestionservice.service.QuestionService;
import com.tsoj.tsojquestionservice.service.QuestionsubmitService;
import com.tsoj.tsojserviceclient.service.UserFeignClient;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * 题目接口
 */
@RestController
@RequestMapping("/")
@Api(tags = "题目管理")
@Slf4j
public class QuestionController {

    @Autowired
    private QuestionService questionService;
    @Resource
    private UserFeignClient userFeignClient;
    @Autowired
    private QuestionsubmitService questionsubmitService;
    @Autowired
    private MaxPageSizePropertise maxPageSizePropertise;
    //增删改查

    /**
     * 创建
     *
     * @param questionAddRequest
     * @return
     */
    @PostMapping("/add")
    @ApiOperation(value = "创建题目")
    public BaseResponse<Long> addQuestion(@RequestBody QuestionAddRequest questionAddRequest) {
        if(questionAddRequest == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数为空");
        }
        Long id = questionService.addQuestion(questionAddRequest);
        return ResultUtils.success(id);
    }

    //删除题目(仅管理员和本人)
    @ApiOperation(value = "删除题目(管理员可用和创建人)")
    @PostMapping("/delete")
    public BaseResponse deleteQuestion(@RequestBody DeleteRequest deleteRequest){
        if(deleteRequest == null || deleteRequest.getId() <= 0){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        //先查询能否删除id是否存在
        Question question = questionService.getById(deleteRequest.getId());
        if(question == null){
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "题目不存在");
        }
        //todo 修改验证方式
        Long userId = ThreadLocalContext.getUserId();
        User user = userFeignClient.getById(userId);
        boolean admin = userFeignClient.isAdmin(user);
        Long userid = question.getUserid();
        if(!admin && !userid.equals(userId)){
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR,"无权限");
        }
        boolean b = questionService.removeById(deleteRequest.getId());
        if(!b){
            return ResultUtils.error(ErrorCode.OPERATION_ERROR,"删除失败");
        }else {
            return ResultUtils.success("删除成功");
        }
    }

    //更新题目（仅管理员 和本人）
    @ApiOperation(value = "更新题目(管理员和创建人)")
    @PostMapping("/update")
    public BaseResponse<Boolean> updateQuestion(@RequestBody QuestionUpdateRequest updateRequest){
        if(updateRequest == null || updateRequest.getId() <= 0){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        //查询id是否存在
        Question question = questionService.getById(updateRequest.getId());
        if(question == null){
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "题目不存在");
        }
        //todo 有问题
        Long userId = ThreadLocalContext.getUserId();
        User user = userFeignClient.getById(userId);
        boolean admin = userFeignClient.isAdmin(user);
        Long userid = question.getUserid();
        if(!admin && !userid.equals(userId)){
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR,"无权限");
        }
        Boolean b = questionService.updateQuestion(updateRequest);
        return ResultUtils.success(b);
    }
    //查找(个人用户)
    //todo查询接口有问题
    @GetMapping("/get/vo")
    @ApiOperation(value = "查询单个题目信息(普通用户)")
    public BaseResponse<QuestionVO> getQuestionVOById(long id){
        if(id <= 0){
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "id不合法");
        }
        Question question = questionService.getById(id);
        if(question == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "题目不存在");
        }
        //进行脱敏处理
        QuestionVO questionVO =questionService.handle(question);
        return ResultUtils.success(questionVO);
    }
    /**
     * 根据 id 获取
     *
     * @param id
     * @return
     */
    @GetMapping("/get/{id}")
    @ApiOperation(value = "获取题目信息根据id")
    public BaseResponse<Question> getQuestionById(@PathVariable long id) {
        if (id <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Question question = questionService.getById(id);
        if (question == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }

        //todo 不是本人或管理员，不能直接获取所有信息
        Long userId = ThreadLocalContext.getUserId();
        User user = userFeignClient.getById(userId);
        boolean admin = userFeignClient.isAdmin(user);
        Long userid = question.getUserid();
        if(!admin && !userid.equals(userId)){
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR,"无权限");
        }
        return ResultUtils.success(question);
    }
    /**
     * 分页获取列表（封装类）个人用户
     *
     * @param questionQueryRequest
     * @return
     */
    @PostMapping("/list/page/vo")
    @ApiOperation(value = "分页获取列表(普通用户)")
    public BaseResponse<Page<QuestionVO>> listQuestionVOByPage(@RequestBody QuestionQueryRequest questionQueryRequest) {
        if(questionQueryRequest == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        //查询参数
        long current = questionQueryRequest.getCurrent();//当前页码
        long size = questionQueryRequest.getPageSize();//每页大小

        if(size > maxPageSizePropertise.getMaxPageSize()){
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数错误");
        }
        Page<Question> page = questionService.page(new Page<>(current, size)
        ,questionService.getQueryWrapper(questionQueryRequest));
        Page<QuestionVO> questionVOPage = questionService.queryVO(page);
        return ResultUtils.success(questionVOPage);
    }
    //todo 后期优化
    /**
     * 分页获取当前用户创建的资源列表
     *
     * @param questionQueryRequest
     * @return
     */
    @ApiOperation(value = "分页获取当前用户创建的资源列表")
    @PostMapping("/my/list/page/vo")
    public BaseResponse<Page<QuestionVO>> listMyQuestionVOByPage(@RequestBody QuestionQueryRequest questionQueryRequest){
        if(questionQueryRequest == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        //获取当前的登录用户
        Long userId = ThreadLocalContext.getUserId();
        questionQueryRequest.setUserId(userId);
        Page<Question> page = questionService.page(new Page<>(questionQueryRequest.getCurrent(),questionQueryRequest.getPageSize())
                ,questionService.getQueryWrapper(questionQueryRequest));
        Page<QuestionVO> questionVOPage = questionService.queryVO(page);
        return ResultUtils.success(questionVOPage);
    }


    /**
     * 分页获取题目列表（仅管理员）
     *
     * @param questionQueryRequest
     * @param request
     * @return
     */
    @ApiOperation(value = "分页获取题目列表(管理员可用)")
    @PostMapping("/list/page")
//todo     @AdminRequire
    public BaseResponse<Page<Question>> listQuestionByPage(@RequestBody QuestionQueryRequest questionQueryRequest,
                                                           HttpServletRequest request) {
        long current = questionQueryRequest.getCurrent();
        long size = questionQueryRequest.getPageSize();
        Page<Question> questionPage = questionService.page(new Page<>(current, size),
                questionService.getQueryWrapper(questionQueryRequest));
        return ResultUtils.success(questionPage);
    }

    private static final Gson GSON = new Gson();
    //编辑题目信息(只能修改自己的) todo 待优化传入信息为空
    @PostMapping("/edit")
    @ApiOperation(value = "修改题目")
    public BaseResponse<Boolean> editQuestion(@RequestBody QuestionEditRequest editRequest){
        if (editRequest == null || editRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Question question = new Question();
        BeanUtils.copyProperties(editRequest, question);
        List<String> tags = editRequest.getTags();
        if (!tags.isEmpty()) {
            question.setTags(GSON.toJson(tags));
        }
        List<JudgeCase> judgeCase = editRequest.getJudgeCase();
        if (!judgeCase.isEmpty()) {
            question.setJudgecase(GSON.toJson(judgeCase));
        }
        JudgeConfig judgeConfig = editRequest.getJudgeConfig();
        if (judgeConfig != null) {
            question.setJudgeconfig(GSON.toJson(judgeConfig));
        }
        // 参数校验
        questionService.validQuestion(question, false);
        //获取用户id
        long id = editRequest.getId();
        // 判断是否存在
        Question oldQuestion = questionService.getById(id);
        ThrowUtils.throwIf(oldQuestion == null, ErrorCode.NOT_FOUND_ERROR);
        //todo 有问题 仅本人或管理员可编
        Long userId = ThreadLocalContext.getUserId();
        User user = userFeignClient.getById(userId);
        boolean admin = userFeignClient.isAdmin(user);
        Long userid = oldQuestion.getUserid();
        if(!admin && !userid.equals(userId)){
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR,"无权限");
        }

        boolean result = questionService.updateById(question);
        return ResultUtils.success(result);
    }


    /**
     * 提交题目
     *
     * @param questionSubmitAddRequest
     * @return 提交记录的 id
     */
    @ApiOperation(value = "提交题目")
    @PostMapping("/do")
    public BaseResponse<Long> doQuestionSubmit(@RequestBody QuestionSubmitAddDto questionSubmitAddRequest) {
        if (questionSubmitAddRequest == null || questionSubmitAddRequest.getQuestionId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 登录才能点赞
        long id = ThreadLocalContext.getUserId();
        long questionSubmitId = questionsubmitService.doQuestionSubmit(questionSubmitAddRequest, id);
        return ResultUtils.success(questionSubmitId);
    }

    /**
     * 题目提交列表分页获取（仅管理员） todo 待优化看是否要做鉴权处理
     */
    @ApiOperation(value = "题目提交列表分页获取 普通用户")
    @PostMapping("/question_submit/list/page")
    public BaseResponse<Page<QuestionSubmitVO>> listPageQuestionSubmit(@RequestBody QuestionSubmitQueryDto questionSubmitQueryDto){

        long current = questionSubmitQueryDto.getCurrent();//当前页码
        long size = questionSubmitQueryDto.getPageSize();//分页大小

        if(size > maxPageSizePropertise.getMaxPageSize()){
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数错误");
        }
        Page<QuestionSubmit> page = questionsubmitService.page(new Page<>(current,size),
                questionsubmitService.getQueryWrapper(questionSubmitQueryDto));
        //todo 有问题 设置用户只能看到自己的代码
        Long userId = ThreadLocalContext.getUserId();
        User user = userFeignClient.getById(userId);
        boolean admin = userFeignClient.isAdmin(user);
        //做脱敏处理
        Page<QuestionSubmitVO> pageQuestionSubmitVO = questionsubmitService.getQuestionSubmitVOList(page,userId);
        return ResultUtils.success(pageQuestionSubmitVO);
    }
    @ApiOperation(value = "题目提交列表分页获取 管理员可用")
    @GetMapping("/question_submit/list/page/admin")
    public BaseResponse<Page<QuestionSubmit>> listPageQuestionSubmit(@RequestBody QuestionSubmitQueryDto questionSubmitQueryDto, HttpServletRequest request){
        if(questionSubmitQueryDto == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        long current = questionSubmitQueryDto.getCurrent();//当前页码
        long size = questionSubmitQueryDto.getPageSize();//分页大小

        if(size > maxPageSizePropertise.getMaxPageSize()){
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数错误");
        }
        //todo 拿到id有问题管理员校验
        Long userId = ThreadLocalContext.getUserId();
        User user = userFeignClient.getById(userId);
        boolean admin = userFeignClient.isAdmin(user);
        if(!admin){
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
        Page<QuestionSubmit> page = questionsubmitService.page(new Page<>(current,size),
                questionsubmitService.getQueryWrapper(questionSubmitQueryDto));
        return ResultUtils.success(page);
    }

//
//    /**
//     * 提交题目
//     *
//     * @param questionSubmitAddRequest
//     * @param request
//     * @return 提交记录的 id
//     */
//    @ApiOperation(value = "提交题目")
//    @PostMapping("/question_submit/do")
//    public BaseResponse<Long> doQuestionSubmit(@RequestBody QuestionSubmitAddDto questionSubmitAddRequest,
//                                               HttpServletRequest request) {
//        if (questionSubmitAddRequest == null || questionSubmitAddRequest.getQuestionId() <= 0) {
//            throw new BusinessException(ErrorCode.PARAMS_ERROR);
//        }
//        // 登录才能点赞
//        long id = ThreadLocalContext.getUserId();
//        long questionSubmitId = questionsubmitService.doQuestionSubmit(questionSubmitAddRequest, id);
//        return ResultUtils.success(questionSubmitId);
//    }


}